import { message, Modal, Upload } from "antd";
import React, { useEffect, useImperativeHandle, useState } from "react";
import { PlusOutlined } from "@ant-design/icons";
import { reqDeleteImg } from "../../api";
import { BASE_IMG_URL } from "../../utils/constants";
// getBase64函数对图片文件进行base64编码
function getBase64(file: any) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = (error) => reject(error);
  });
}

// PicWall组件上接收一个自定义属性cRef 用于ref获取
interface cref {
  cRef?: any;
  imgs?: any;
}

// 照片墙组件forwardRef
const PicWall: React.FC<cref> = (props) => {
  //对话框是否可见状态
  const [previewVisible, setpreviewVisible] = useState(false);
  //预览上传的图片
  const [previewImage, setpreviewImage] = useState("");
  //title状态
  const [previewTitle, setpreviewTitle] = useState("");

  // 因为fileList结构比较复杂 所以ts声明要详细一点
  // 由对象组成的数组 可以直接写成<Array<any>>泛型 不然会因为类型问题在使用的时候TS检查报错
  const [fileList, setfileList] = useState<Array<any>>([]);

  //getImagesList方法 用于获取fileList的内容
  const getImagesList = () => {
    return fileList.map((item: any) => item.name);
  };

  // 在useEffect检测当前组件获得的props.imgs 如果当前组件拿到了正确的props.imgs
  // 就map处理props.imgs并且赋值给上传图片的fileList中
  // 就实现了修改页面就能保存以及上传的图片信息
  useEffect(() => {
    if (props.imgs && props.imgs.length >= 1) {
      let res;
      res = props.imgs.map((img: any, index: any) => ({
        uid: -index,
        name: img,
        status: "done",
        url: BASE_IMG_URL + img,
      }));
      setfileList(res);
    }
  }, [props.imgs]);

  // 根据官方文档解决了 很多内容的函数式组件ref不起作用的问题
  // useImperativeHandle可以强制把子组件的方法向外暴露
  //
  useImperativeHandle(props.cRef, () => ({
    getImagesList: getImagesList,
  }));

  // 隐藏对话框
  const handleCancel = () => setpreviewVisible(false);

  // 点击图片预览大图
  const handlePreview = async (file: any) => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj);
    }
    setpreviewImage(file.url || file.preview);
    // 对话框大图预览
    setpreviewVisible(true);
    setpreviewTitle(
      file.name || file.url.substring(file.url.lastIndexOf("/") + 1)
    );
  };

  // 当上传或者删除图片的时候 重新加载fileList 就会对应做出修改 参数file就是当前上传的那个
  const handleChange = async ({ file, fileList }: any) => {
    if (file.status === "done") {
      const res = file.response;
      if (res.status === 0) {
        message.success("上传图片成功！");
        const { name, url } = res.data;
        file = fileList[fileList.length - 1];
        file.name = name;
        file.url = url;
      } else {
        message.error("上传图片失败！");
      }
    } else if (file.status === "removed") {
      // 删除图片 要调用接口删除后台的图片
      const {
        data: { status: res },
      } = await reqDeleteImg(file.name);
      // 返回值会反映删除是否成功
      if (res === 0) {
        message.success("图片删除成功！");
      } else {
        message.error("图片删除失败！");
      }
    }

    setfileList(fileList);
  };

  // 上传图片的按钮 内容以及图标
  const uploadButton = (
    <div>
      <PlusOutlined />
      <div style={{ marginTop: 8 }}>Upload</div>
    </div>
  );

  return (
    <>
      <Upload
        // 接收文件的类型 图片
        accept="image/*"
        // 图片上传的地址
        action="/manage/img/upload"
        // http://localhost:5000/manage/img/upload
        listType="picture-card"
        // 照片墙的内容list
        fileList={fileList}
        // 预览 --  也就是点击图片上的研究
        onPreview={handlePreview}
        // onChange 就是添加图片或者点击图片小垃圾桶删除图片
        onChange={handleChange}
        // 传输的请求参数名 参数值就是上传的文件
        name="image"
      >
        {/* 图片上传上限8个 */}
        {fileList.length >= 8 ? null : uploadButton}
      </Upload>
      {/* 对话框在预览大图显示 点叉叉取消对话框 */}
      <Modal
        // 是否可见
        visible={previewVisible}
        // 对话框标题
        title={previewTitle}
        footer={null}
        // onCancel点击取消 modal隐藏
        onCancel={handleCancel}
      >
        <img alt="example" style={{ width: "100%" }} src={previewImage} />
      </Modal>
    </>
  );
};

// const PicWall = React.forwardRef<any>((props, ref) => (
//   <div ref={ref}>
//     <PicWallx {...props}></PicWallx>
//   </div>
// ));

export default PicWall;
// 视频p78
